import { Snake } from '../entities/Snake';
import { InputManager } from '../systems/InputManager';
import { Renderer } from '../systems/Renderer';
import { CollisionSystem } from '../systems/CollisionSystem';
import { Vector2D } from '../utils/Vector2D';
import { GameModeManager, GameMode } from '../systems/GameModeManager';
import { ProgressionManager } from '../systems/ProgressionManager';
import { EnvironmentManager } from '../systems/EnvironmentManager';
import { FoodManager } from '../systems/FoodManager';
import { UIRenderer } from '../systems/UIRenderer';
import { MenuManager } from '../systems/MenuManager';
import { MenuRenderer } from '../systems/MenuRenderer';
import { SkinSystem } from '../systems/SkinSystem';

export class Game {
    private canvas: HTMLCanvasElement;
    private ctx: CanvasRenderingContext2D;
    private snake: Snake;
    private inputManager: InputManager;
    private renderer: Renderer;
    private collisionSystem: CollisionSystem;
    private gameState: 'menu' | 'running' | 'paused' | 'over' = 'menu';
    private score: number = 0;
    private gameModeManager: GameModeManager;
    private progressionManager: ProgressionManager;
    private environmentManager: EnvironmentManager;
    private foodManager: FoodManager;
    private uiRenderer: UIRenderer;
    private menuManager: MenuManager;
    private menuRenderer: MenuRenderer;
    private skinSystem: SkinSystem;

    constructor() {
        this.initializeCanvas();
        this.initializeSystems();
        this.initializeGameObjects();
        this.setupEventListeners();
    }

    private setupEventListeners(): void {
        window.addEventListener('startGame', () => {
            this.gameState = 'running';
            this.restart();
        });

        window.addEventListener('selectGameMode', ((event: CustomEvent) => {
            const mode = event.detail.mode as GameMode;
            this.gameModeManager.setMode(mode);
            this.gameState = 'running';
            this.restart();
        }) as EventListener);
    }

    private initializeCanvas(): void {
        this.canvas = document.getElementById('gameCanvas') as HTMLCanvasElement;
        this.ctx = this.canvas.getContext('2d')!;
        
        // 设置画布大小为窗口大小
        this.canvas.width = window.innerWidth * 0.8;
        this.canvas.height = window.innerHeight * 0.8;

        // 监听窗口大小变化
        window.addEventListener('resize', () => {
            this.canvas.width = window.innerWidth * 0.8;
            this.canvas.height = window.innerHeight * 0.8;
        });
    }

    private initializeSystems(): void {
        this.inputManager = new InputManager();
        this.environmentManager = new EnvironmentManager();
        this.skinSystem = new SkinSystem();
        this.renderer = new Renderer(this.ctx, this.environmentManager);
        this.collisionSystem = new CollisionSystem();
        this.gameModeManager = new GameModeManager();
        this.progressionManager = new ProgressionManager();
        this.foodManager = new FoodManager(this.environmentManager);
        this.foodManager.updateCanvasSize(this.canvas.width, this.canvas.height);
        this.uiRenderer = new UIRenderer(this.ctx);
        this.menuManager = new MenuManager(this.skinSystem, this.progressionManager);
        this.menuRenderer = new MenuRenderer(this.canvas, this.menuManager);
        
        // 监听皮肤变化事件
        document.addEventListener('skinChanged', (event: CustomEvent) => {
            document.body.setAttribute('data-snake-skin', event.detail.skin);
        });
    }

    private initializeGameObjects(): void {
        // 初始化蛇的位置在画布中心
        const startPos = new Vector2D(
            this.canvas.width / 2,
            this.canvas.height / 2
        );
        this.snake = new Snake(startPos);

        // 将蛇的引用传递给FoodManager
        this.foodManager.setSnake(this.snake);

        // 初始化食物
        this.foodManager.generateFood();
    }



    public update(deltaTime: number): void {
        if (this.gameState === 'menu' || this.gameState === 'over') return;

        // 更新输入
        const input = this.inputManager.getInput();
        
        // 应用天气影响到控制灵敏度
        const sensitivity = this.environmentManager.getControlSensitivity();
        input.direction = input.direction.multiply(sensitivity);

        // 更新环境
        this.environmentManager.update(deltaTime, this.canvas.width, this.canvas.height);
        
        // 更新游戏模式
        this.gameModeManager.update(deltaTime, this.snake, this.foodManager.getFoods());

        // 更新蛇的状态（应用属性升级效果）
        const speedMultiplier = this.progressionManager.getUpgradeEffect('speed');
        this.snake.update(deltaTime * speedMultiplier, input);

        // 检查碰撞
        this.handleCollisions();

        // 更新食物生成
        this.foodManager.update();
    }

    private handleCollisions(): void {
        // 检查与食物的碰撞（应用范围升级效果）
        const rangeMultiplier = this.progressionManager.getUpgradeEffect('range');
        const foods = this.foodManager.getFoods();

        // 处理磁化效果
        if (this.snake.getState().magnetized) {
            const magnetRange = 150; // 磁化效果的吸引范围
            const attractionSpeed = 2; // 食物被吸引的速度

            for (const food of foods) {
                if (food.getType() === 'energy' && 
                    this.collisionSystem.checkMagnetRange(this.snake.getHead(), food, magnetRange)) {
                    const foodPos = food.getPosition();
                    const headPos = this.snake.getHead();
                    const direction = headPos.subtract(foodPos).normalize();
                    food.setPosition(foodPos.add(direction.multiply(attractionSpeed)));
                }
            }
        }

        for (const food of [...foods]) {
            if (this.collisionSystem.checkCollision(this.snake.getHead(), food, rangeMultiplier)) {
                const foodType = food.getType();
                const foodValue = food.getValue();
                
                switch (foodType) {
                    case 'energy':
                        const lengthMultiplier = this.progressionManager.getUpgradeEffect('length');
                        this.snake.grow(lengthMultiplier);
                        this.score += foodValue;
                        break;
                    case 'poison':
                        this.snake.applyEffect('poisoned', 5000);
                        this.score += foodValue;
                        break;
                    case 'magnet':
                        this.snake.applyEffect('magnetized', 8000);
                        this.score += foodValue;
                        break;
                }
                
                this.progressionManager.updateScore(this.score);
                this.foodManager.removeFood(food);
            }
        }

        // 检查与边界的碰撞
        if (this.collisionSystem.checkBoundaryCollision(this.snake.getHead(), this.canvas)) {
            this.gameOver();
        }

        // 检查自身碰撞
        if (this.collisionSystem.checkSelfCollision(this.snake)) {
            this.gameOver();
        }
    }

    private gameOver(): void {
        this.gameState = 'over';
        // 游戏结束状态会在render方法中处理UI显示
    }

    public restart(): void {
        // 重置游戏状态
        this.gameState = 'running';
        this.score = 0;

        // 重置蛇
        const startPos = new Vector2D(
            this.canvas.width / 2,
            this.canvas.height / 2
        );
        this.snake = new Snake(startPos);

        // 更新FoodManager中的蛇引用
        this.foodManager.setSnake(this.snake);
        
        // 更新SkinSystem中的蛇引用
        this.skinSystem.setSnake(this.snake);

        // 重置食物管理器
        this.foodManager.reset();

        // 重置系统状态
        this.environmentManager.reset();
        this.gameModeManager.setMode('classic');
        this.progressionManager.reset();
    }

    public render(): void {
        // 清除画布
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        
        if (this.gameState === 'menu') {
            // 在菜单状态下，使用MenuRenderer渲染菜单
            this.menuRenderer.render();
            return;
        }
        
        // 使用renderer渲染游戏场景
        this.renderer.render(this.snake, this.foodManager.getFoods());
        
        // 渲染UI
        this.uiRenderer.renderScore(this.score);
        if (this.gameState === 'over') {
            const buttonBounds = this.uiRenderer.renderGameOver(this.score, this.canvas);
            
            // 添加点击事件监听
            if (!this.canvas.onclick) {
                this.canvas.onclick = (event) => {
                    if (this.gameState !== 'over') return;

                    const rect = this.canvas.getBoundingClientRect();
                    const x = event.clientX - rect.left;
                    const y = event.clientY - rect.top;

                    // 检查是否点击了重新开始按钮
                    if (x >= buttonBounds.restartButton.buttonX && 
                        x <= buttonBounds.restartButton.buttonX + buttonBounds.restartButton.buttonWidth &&
                        y >= buttonBounds.restartButton.buttonY && 
                        y <= buttonBounds.restartButton.buttonY + buttonBounds.restartButton.buttonHeight) {
                        this.restart();
                        this.canvas.onclick = null; // 移除点击事件监听
                    }
                    
                    // 检查是否点击了返回主菜单按钮
                    if (x >= buttonBounds.menuButton.buttonX && 
                        x <= buttonBounds.menuButton.buttonX + buttonBounds.menuButton.buttonWidth &&
                        y >= buttonBounds.menuButton.buttonY && 
                        y <= buttonBounds.menuButton.buttonY + buttonBounds.menuButton.buttonHeight) {
                        this.gameState = 'menu';
                        this.canvas.onclick = null; // 移除点击事件监听
                    }
                };
            }
        }
    }


}